<?php

namespace App\Http\Controllers\Admin\v1;

use App\Http\Controllers\Controller;
use App\Models\ChargingScheme;
use App\Models\ApiGateway;
use Illuminate\Http\Request;
use App\Http\Controllers\ApiController;
use App\Models\Admin;
use App\Models\ApiKey;
use App\Models\Customer;
use App\Models\Charge;
use App\Models\TimePeriod;
use App\Services\Utils\Guard;
use App\Http\Requests\Admin\v1\AdminLoginRequest;
use App\Http\Requests\Admin\v1\ChargingSchemeRequest;
use App\Http\Requests\Admin\v1\CreateApiKeyRequest;
use App\Exceptions\ApiAbstractException;
use App\Exceptions\ApiErrCode;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;
use Illuminate\Support\Arr;
use function Clue\StreamFilter\append;

class AdminController extends ApiController
{
    public function login(AdminLoginRequest $request)
    {
        $email = $request->email;
        $password = $request->password;

        $admin = Admin::findByEmailPassword($email, $password);
        $this->checkAdminExist($admin);
        $token = Guard::JWTAdminLogin($admin);
        return $this->response(compact('admin', 'token'));
    }

    public function createApiKey(CreateApiKeyRequest $request)
    {
        if($request->type == 2){ //按时间段计费
            $type_id = TimePeriod::insertGetId([
                'start_time' => $request->start_time,
                'end_time' => $request->end_time,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
            ]);
            $this->checkItemExist($type_id, '添加方案失败，请重试', ApiErrCode::OPERATE_FAILED);
        }else{
            $type_id = null;
        }

        $apikey = $this->insertApiKey($request->only('name', 'description', 'type'), $request->get('customer_id'), $type_id);
        return $this->response(compact('apikey'));
    }

    private function insertApiKey($data, $customer_id, $type_id)
    {
        $api_key = new ApiKey;
        $api_key->customer_id = $customer_id;
        $api_key->key = $api_key->key;
        $api_key->secret = $api_key->secret;
        $api_key->name = $data['name'];
        $api_key->description = $data['description'];
        $api_key->status = 'unactive';
        $api_key->type = $data['type'];
        $api_key->type_id = $type_id;
        $api_key->save();

        $apikey = $api_key->findByKey($api_key->key);
        return $apikey;
    }

    public function apikeys(Request $request)
    {
//        $filers =$request->only('name', 'apikey_id', 'apikey_name', 'status');
//        $apikeys = array();
//        if ($filers['name'] == null){
//            $apikeys =ApiKey::where('id', $filers['apikey_id'])->where('name','LIKE', '%'.$filers['apikey_name'].'%')->get();
//        }else{
//            $apikeys = ApiKey::with(['customer' => function($query) use ($filers){
//            $query->where('name', 'LIKE', '%'.$filers['name'].'%');
////                return $query->where('name', $filers['name']);
//            }])->orwhere('id', $filers['apikey_id'])->orwhere('name','LIKE', '%'.$filers['apikey_name'].'%')->get();
//        }

        $where = $this->ApiKeySearch($request->only('name', 'apikey_id', 'apikey_name', 'status'));
        $per_page = $request->per_page;

        $apikeys = ApiKey::where($where)
                            ->whereNull('deleted_at')
                            ->select('id', 'customer_id', 'name', 'status', 'type', 'type_id', 'created_at')
                            ->paginate($per_page);
        $this->mappingApiKeys($apikeys);
        return $this->response(compact('apikeys'));
    }

    public function mappingApiKeys($apikeys)
    {
        foreach($apikeys as $item){
            if (!empty($item->type_id)) {
                $period = TimePeriod::find($item->type_id);
                $item['start_time'] = $period->start_time;
                $item['end_time'] = $period->end_time;
                if ($period->end_time < Carbon::now()) {
                    $item['status'] = 'outdated';
                }
            }
            $item->customer;
        }
    }

    //todo 需添加模型过滤
    public static function ApiKeySearch($validated)
    {
         return function($query) use ($validated){
             extract($validated);

             if(!empty($validated['name'])){    //过滤用户名称
                 $ids = Customer::where('name','like',"%{$validated['name']}%")->pluck('id');
                 if($ids){
                     $query->whereIn('customer_id', $ids);
                 }
             }
             if(!empty($validated['apikey_id'])){   //过滤apikey的id
                 $query->where('id', $validated['apikey_id']);
             }
             if(!empty($validated['apikey_name'])){ //过滤apikey的名称
                 $query->where('name', 'like', '%'.$validated['apikey_name'].'%');
             }
             if(!empty($validated['status'])){  //过滤apikey的状态
                 $query->where('status', $validated['status']);
             }
         };
    }

    public function apiGateways(Request $request)
    {
        $gateways = ApiGateway::where(['apikey_id' => $request->apikey_id, 'group' => $request->group])
                                ->select('apikey_id', 'group', 'endpoint')
                                ->get();
        return $this->response(compact('gateways'));
    }

    public function gatewayStatus(Request $request)
    {
        $apigateway = new ApiGateway;
        $apikey_gateway = $apigateway->where([
                'apikey_id' => $request->apikey_id,
                'group' => $request->group,
                'endpoint' => $request->endpoint,
            ])->first();
        if($request->authorize == 0 && isset($apikey_gateway)){    //取消授权关联api
            $apikey_gateway->delete();
        }else if($request->authorize == 1 && !isset($apikey_gateway)){    //授权关联api
            $apigateway->apikey_id = $request->apikey_id;
            $apigateway->group = $request->group;
            $apigateway->endpoint = $request->endpoint;
            $apigateway->save();
        }else{
            return $this->response(['code' => 400]);
        }
        return $this->response(['code' => 200]);
    }

    public function delete(Request $request)
    {
        $apikey_id = $request->get('apikey_id');
        $apikey = ApiKey::find($apikey_id);
        $this->checkParamError($apikey, trans('checker.check_apikey_id_error'));
        $apikey->delete();
        return $this->response(['code' => 200]);
    }

//    public function addChargingScheme(ChargingSchemeRequest $request)
//    {
//        $prices = \json_encode($request->prices);
//        $type = $request->type;
//        $remark = $request->remark;
//        $start_time = $request->input('start_time');
//        $end_time = $request->input('end_time');
//
//        $id = ChargingScheme::insertGetId([
//            'prices'     => $prices,
//            'type'       => $type,
//            'remark'     => $remark,
//            'start_time' => $start_time,
//            'end_time'   => $end_time,
//            'created_at' => Carbon::now(),
//            'updated_at' => Carbon::now()
//        ]);
//        if($id){
//            $data = ChargingScheme::where('id', $id)->get();
//        }
//        return $this->response(compact('data'));
//    }

    public function chargingSchemes(Request $request)
    {
        $per_page = $request->per_page;
        $charging_schemes = ChargingScheme::paginate($per_page);
        return $this->response(compact('charging_schemes'));
    }

    public function updateChargingScheme(Request $request)
    {
        $id = $request->id;
        $price_scheme =  ChargingScheme::find($id);
        $this->checkParamError($price_scheme, '修改失败，数据不存在');

        $priceStr = $price_scheme->prices;
        $pricesObj = \json_decode($priceStr);
        $group = $request->group;
        $endpoint = $request->endpoint;
        $pricesObj->$group->$endpoint->price = $request->price*100;
        // data_set($pricesObj, $request->group.'.'.$request->endpoint.'.price', $request->price*100, $overwrite=true);
        $price_scheme->prices =  \json_encode($pricesObj);
        $price_scheme->updated_at = Carbon::now();
        $price_scheme->save();

        return $this->response(compact('price_scheme'));
    }

    public function updateApiKeyStatus(Request $request)
    {
        $apikey_id = $request->apikey_id;

        $apikey = ApiKey::find($apikey_id);
        $this->checkParamError($apikey, trans('checker.check_apikey_id_error'));

        if ($request->has('start_time') || $request->has('end_time')) {
            $this->updateTimePeriod($apikey, $request->start_time, $request->end_time);
        }
        $apikey->status = $request->status;
        $apikey->save();
        return $this->response(compact('apikey'));
    }

    public function updateTimePeriod($apikey, $start_time, $end_time)
    {
        if ($apikey->type == 2) {
            TimePeriod::where('id', $apikey->type_id)
                        ->update([
                            'start_time' => $start_time,
                            'end_time' => $end_time
                        ]);
        }
    }

    public function customers(Request $request)
    {
        //todo 需添加模型过滤
        $where = [];
        $name = $request->name;
        if(!empty($name)){
            $where[] = ['name','like', "%{$name}%"];
        }
        $phone = $request->phone;
        if(!empty($phone)){
            $where[] = ['phone', 'like', "%{$phone}%"];
        }
        $locked = $request->locked;
        if(isset($locked)){
            $where['locked'] = $locked;
        }

        $per_page = $request->per_page;
        $customers = Customer::where($where)->paginate($per_page);

        return $this->response(compact('customers'));
    }

    public function updateCustomerStatus(Request $request)
    {
        $customer_id = $request->customer_id;
        $customer = Customer::find($customer_id);
        $this->checkParamError($customer, '该用户不存在');

        $customer->locked = $request->locked;
        $customer->save();
        return $this->response(compact('customer'));
    }

    public function charges(Request $request)
    {
        $customer_id = $request->customer_id;
        $customer = Customer::find($customer_id);
        $this->checkParamError($customer, '该用户不存在');
        $per_page = $request->per_page;
        $charges = Charge::where('customer_id', $customer_id)->latest()->paginate($per_page);
        foreach ($charges as $value) {
            $value['change_before'] = $value['change_before']/100.0;
            $value['change_after'] = $value['change_after']/100.0;
        }
        return $this->response(compact('charges'));
    }

    protected function manualRecharge(Request $request)
    {
        $charges = Charge::where('customer_id', $request->customer_id)->latest()->value('change_after');
        $amount = empty($charges) ? 0 : $charges;
        $change_after = intval($amount + ($request->amount)*100);

        $charge = new Charge;
        $charge->customer_id = $request->customer_id;
        $charge->change_before = $amount;
        $charge->change_after = $change_after;
        $charge->change_type = '';
        $charge->remark = '奖励';
        $charge->created_at = Carbon::now();
        $charge->save();
        return $this->response(['code' => 200]);
    }
}
